package com.ruoyi.student.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.student.domain.PhdAdmissionInfo;
import com.ruoyi.student.service.IPhdAdmissionInfoService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 博士录取信息Controller
 *
 * @author ruoyi-mate
 * @date 2025-09-10
 */
@RestController
@RequestMapping("/student/bslq")
public class PhdAdmissionInfoController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(PhdAdmissionInfoController.class);

    @Autowired
    private IPhdAdmissionInfoService phdAdmissionInfoService;

    /**
     * 查询博士录取信息列表
     */
//    @PreAuthorize("@ss.hasPermi('student:bslq:list')")
    @GetMapping("/list")
    public TableDataInfo list(PhdAdmissionInfo phdAdmissionInfo)
    {
        startPage();
        List<PhdAdmissionInfo> list = phdAdmissionInfoService.selectPhdAdmissionInfoList(phdAdmissionInfo);
        return getDataTable(list);
    }

    /**
     * 导出博士录取信息列表
     */
/*    @PreAuthorize("@ss.hasPermi('student:bslq:export')")*/
    @Log(title = "博士录取信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, PhdAdmissionInfo phdAdmissionInfo)
    {
        List<PhdAdmissionInfo> list = phdAdmissionInfoService.selectPhdAdmissionInfoList(phdAdmissionInfo);
        ExcelUtil<PhdAdmissionInfo> util = new ExcelUtil<PhdAdmissionInfo>(PhdAdmissionInfo.class);
        util.exportExcel(response, list, "博士录取信息数据");
    }

    /**
     * 获取博士录取信息详细信息
     */
/*    @PreAuthorize("@ss.hasPermi('student:bslq:query')")*/
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return success(phdAdmissionInfoService.selectPhdAdmissionInfoById(id));
    }

    /**
     * 新增博士录取信息
     */
/*    @PreAuthorize("@ss.hasPermi('student:bslq:add')")*/
    @Log(title = "博士录取信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PhdAdmissionInfo phdAdmissionInfo)
    {
        // 新增前检查学号是否已存在
        if (phdAdmissionInfo.getStudentId() != null &&
                phdAdmissionInfoService.checkStudentIdExists(phdAdmissionInfo.getStudentId().trim())) {
            return AjaxResult.error("学号已存在，无法新增");
        }
        return toAjax(phdAdmissionInfoService.insertPhdAdmissionInfo(phdAdmissionInfo));
    }

    /**
     * 修改博士录取信息
     */
/*    @PreAuthorize("@ss.hasPermi('student:bslq:edit')")*/
    @Log(title = "博士录取信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PhdAdmissionInfo phdAdmissionInfo)
    {
        return toAjax(phdAdmissionInfoService.updatePhdAdmissionInfo(phdAdmissionInfo));
    }

    /**
     * 删除博士录取信息
     */
/*    @PreAuthorize("@ss.hasPermi('student:bslq:remove')")*/
    @Log(title = "博士录取信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(phdAdmissionInfoService.deletePhdAdmissionInfoByIds(ids));
    }

    /**
     * 导入博士录取信息
     */
    @Log(title = "博士录取信息导入", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<PhdAdmissionInfo> util = new ExcelUtil<>(PhdAdmissionInfo.class);
        List<PhdAdmissionInfo> dataList = util.importExcel(file.getInputStream());
        LoginUser loginUser = getLoginUser();
        String operName = loginUser.getUsername();

        // 导入结果统计
        int totalCount = dataList.size();
        int successCount = 0;
        List<FailedStudent> failedStudents = new ArrayList<>();

        log.info("开始导入博士录取信息，总条数：{}，操作人：{}", totalCount, operName);

        for (PhdAdmissionInfo info : dataList) {
            // 构建失败信息对象
            FailedStudent failed = new FailedStudent();
            failed.setStudentId(info.getStudentId() != null ? info.getStudentId() : "未知");
            failed.setName(info.getName() != null ? info.getName() : "未知");
            failed.setCandidateNumber(info.getCandidateNumber() != null ? info.getCandidateNumber() : "未知");

            try {
                // 1. 学号处理：去除前后所有空格
                if (info.getStudentId() != null) {
                    String trimmedStudentId = info.getStudentId().trim();
                    info.setStudentId(trimmedStudentId);
                    failed.setStudentId(trimmedStudentId); // 更新失败信息中的学号
                } else {
                    failed.setReason("学号不能为空");
                    failedStudents.add(failed);
                    continue; // 学号为空直接跳过
                }

                // 2. 检查学号是否已存在
                boolean studentIdExists = phdAdmissionInfoService.checkStudentIdExists(info.getStudentId());
                if (studentIdExists) {
                    // 学号已存在的处理逻辑
                    if (updateSupport) {
                        // 如果允许更新，执行更新操作
                        phdAdmissionInfoService.updatePhdAdmissionInfo(info);
                        successCount++;
                        log.info("更新学生信息，学号：{}", info.getStudentId());
                    } else {
                        failed.setReason("学号已存在（未开启更新模式）");
                        failedStudents.add(failed);
                    }
                    continue;
                }

                // 3. 准备新增数据
                info.setId(IdUtils.fastSimpleUUID());
                info.setImportOperator(operName);
                info.setImportTime(new Date());

                // 4. 执行新增操作
                phdAdmissionInfoService.insertPhdAdmissionInfo(info);
                successCount++;
                log.info("新增学生信息，学号：{}", info.getStudentId());

            } catch (Exception e) {
                // 捕获其他异常
                String errorMsg = e.getMessage();
                if (errorMsg != null && errorMsg.length() > 100) {
                    errorMsg = errorMsg.substring(0, 100) + "...";
                }
                failed.setReason("处理失败：" + (errorMsg != null ? errorMsg : "未知错误"));
                failedStudents.add(failed);
                log.error("导入学生信息失败，学号：{}，原因：{}", info.getStudentId(), e.getMessage(), e);
            }
        }

        // 统一返回格式
        AjaxResult result = AjaxResult.success();
        result.put("totalCount", totalCount);
        result.put("successCount", successCount);
        result.put("failedCount", failedStudents.size());
        result.put("failedStudents", failedStudents);

        // 构建提示消息
        String msg = String.format("导入完成，共处理%d条，成功%d条，失败%d条",
                totalCount, successCount, failedStudents.size());
        result.put("msg", msg);

        log.info(msg + "，操作人：{}", operName);
        return result;
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response)
    {
        ExcelUtil<PhdAdmissionInfo> util = new ExcelUtil<PhdAdmissionInfo>(PhdAdmissionInfo.class);
        util.importTemplateExcel(response, "博士录取信息模板");
    }

    /**
     * 失败学生信息类
     */
    public static class FailedStudent {
        private String studentId;      // 学号
        private String name;           // 姓名
        private String candidateNumber;// 考生号
        private String reason;         // 失败原因

        // Getters and Setters
        public String getStudentId() {
            return studentId;
        }

        public void setStudentId(String studentId) {
            this.studentId = studentId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getCandidateNumber() {
            return candidateNumber;
        }

        public void setCandidateNumber(String candidateNumber) {
            this.candidateNumber = candidateNumber;
        }

        public String getReason() {
            return reason;
        }

        public void setReason(String reason) {
            this.reason = reason;
        }
    }
}
